﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using GO_Test_1.Components;
using Microsoft.Xna.Framework;

namespace GO_Test_1 {

	public static class BehaviorManager {

		public static void Update(GameTime gameTime) {
			Guid? blockToRemove = null;

			foreach (var id in ComponentManager.IDs) {
				GoType goType = ComponentManager.Types[id];

				//=====( Begin Move )==========================================

				if (ComponentManager.Movements.ContainsKey(id)) {
					Movement movement = ComponentManager.Movements[id];
					movement.Velocity = movement.Speed*gameTime.ElapsedGameTime.Ticks/TimeSpan.TicksPerSecond*movement.Direction;
					ComponentManager.Movements[id] = movement;
					ComponentManager.Positions[id] += movement.Velocity; // todo: Add acceleration here.
					// Move the bounding box.
					if (goType == GoType.Ball) {
						Rectangle boundingBox = ComponentManager.BoundingBoxes[id];
						Vector2 position = ComponentManager.Positions[id];
						boundingBox.X = (int) position.X;
						boundingBox.Y = (int) position.Y;
						ComponentManager.BoundingBoxes[id] = boundingBox;
					}
				}

				//=====( End Move )============================================
				///////////////////////////////////////////////////////////////
				//=====( Begin Collision )=====================================

				if (goType == GoType.Ball) {
					Rectangle ball = ComponentManager.BoundingBoxes[id];
					Movement ballMovement = ComponentManager.Movements[id];

					// Collision with walls.
					Movement? wallReflection = CollisionHelper.ReflectBallOffWalls(ball, ballMovement, Game1.gameBounds);
					if (wallReflection != null) {
						ComponentManager.Movements[id] = wallReflection.Value;
					}

					// Collision with blocks.
					// todo: pull this one time at beginning.
					IList<KeyValuePair<Guid, Rectangle>> blocks = (from bb in ComponentManager.BoundingBoxes
					                                               join t in ComponentManager.Types on bb.Key equals t.Key
					                                               where t.Value == GoType.Block
					                                               select bb).ToList();
					foreach (var keyValuePair in blocks) {
						if (ball.Intersects(keyValuePair.Value)) {
							// Remove the block.
							blockToRemove = keyValuePair.Key;
							// Reflect the ball.
							Rectangle block = keyValuePair.Value;
							ComponentManager.Movements[id] = CollisionHelper.ReflectBall(ball, ballMovement, block);
							break; // Only one hit allowed.
						}
					}
				}

				//=====( End Collision )=======================================
			}

			if (blockToRemove != null) {
				ComponentManager.RemoveEntity(blockToRemove.Value);
			}
		}

	}

}